package com.example.demo;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.*;
import org.springframework.data.domain.ExampleMatcher.GenericPropertyMatchers;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

// 如果不专门指定名字，默认相当于驼峰字（userServiceJpaImpl）
@Service
public class UserServiceJpaImpl implements UserService {

    @Autowired
    private UserRepository userRepository;

    @Override
    public int create(String name, Integer age, String email) {
        User user = userRepository.save(new User(name, age, email));
        return user.getId().intValue();
    }

    @Override
    public List<User> getByName(String name) {
        List<User> users = userRepository.findByNameLike(name);
        return users;
    }

    @Override
    public int deleteByName(String name) {
        User user = userRepository.findByName(name);
        userRepository.delete(user);
        return 1;
    }

    @Override
    public int getAllUserCount() {
        return (int) userRepository.count();
    }

    @Override
    public List<User> getAllUsers() {
        List<User> users = userRepository.findAll();
        return users;
    }

    @Override
    public int deleteAllUsers() {
        userRepository.deleteAll();
        return 1;
    }

    @Override
    public List<User> getPageAllUsers(int page, int size) {
        User user = new User();
        user.setName("刘谷川"); // 查询条件
        // 创建查询参数
        Example<User> example = Example.of(user);

        // 姓名采用“开始匹配”的方式查询
        user.setName("刘"); // 查询条件
        ExampleMatcher matcher = ExampleMatcher.matching().withMatcher("name", GenericPropertyMatchers.startsWith())
                .withIgnorePaths("email"); // 忽略属性
        Example<User> exampleMatcher = Example.of(user, matcher); // Example根据域对象和配置创建一个新的ExampleMatcher

        // 获取排序对象
        Sort sort = new Sort(Sort.Direction.DESC, "id");
        // 创建分页对象（page 参数是从 0 开始的。这意味着如果你想获取第一页的数据，你应该传入 page 值为 0）
        return userRepository.findAll(exampleMatcher, PageRequest.of(page - 1, size, sort)).getContent();
    }

    @Override
    public Page<User> getPageInfoAllUsers(int page, int size) {
        // page 参数是从 0 开始的。这意味着如果你想获取第一页的数据，你应该传入 page 值为 0
        Page<User> all = userRepository.findAll(getUserSpecificationAndOr(),
                PageRequest.of(page - 1, size, Sort.by(Sort.Direction.DESC, "id")));
        return all;
    }

    private Specification<User> getUserSpecificationAnd() {
        Specification<User> specification = (Specification<User>) (root, query, criteriaBuilder) -> {
            List<Predicate> predicates = new ArrayList<>();
            predicates.add(criteriaBuilder.like(root.get("name").as(String.class), "刘" + "%"));// 姓like刘
            predicates.add(criteriaBuilder.equal(root.get("email").as(String.class), "lgc653@qq.com"));// 邮件地址
            predicates.add(criteriaBuilder.ge(root.get("age").as(BigDecimal.class), new BigDecimal("10")));// 年龄大于10
            predicates.add(criteriaBuilder.isNotNull(root.get("email").as(String.class)));// 邮件地址不为空（仅为演示isNotNull）
            if (predicates.isEmpty()) {
                return criteriaBuilder.isNotNull(root.get("id"));
            }
            return criteriaBuilder.and(predicates.toArray(new Predicate[0]));
        };
        return specification;
    }

    private Specification<User> getUserSpecificationAndOr() {
        Specification<User> specification = (Specification<User>) (root, query, criteriaBuilder) -> {
            List<Predicate> listAnd = new ArrayList<Predicate>();
            listAnd.add(criteriaBuilder.like(root.get("name").as(String.class), "刘" + "%"));// 姓like刘
            listAnd.add(criteriaBuilder.ge(root.get("age").as(BigDecimal.class), new BigDecimal("10")));// 年龄大于10
            Predicate preAnd = criteriaBuilder.and(listAnd.toArray(new Predicate[listAnd.size()]));
            List<Predicate> listOr = new ArrayList<Predicate>();
            listOr.add(criteriaBuilder.equal(root.get("email").as(String.class), "lgc653@qq.com"));// 邮件地址
            listOr.add(criteriaBuilder.isNotNull(root.get("email").as(String.class)));// 邮件地址不为空（仅为演示isNotNull）
            Predicate preOr = criteriaBuilder.or(listOr.toArray(new Predicate[listOr.size()]));
            if (listAnd.isEmpty() && listOr.isEmpty()) {
                return criteriaBuilder.isNotNull(root.get("id"));
            }
            return query.where(preAnd, preOr).getRestriction();
        };
        return specification;
    }

}